import { Component } from 'react'
import { View, Button, Input, Canvas, Image } from '@tarojs/components'
import Taro from '@tarojs/taro'
import './index.scss'

interface ImageInfo {
  width: number;
  height: number;
  path: string;
}

type IndexState = {
  name: string,
  images: ImageInfo[];
  canvasHeight: number;
  setting: SettingType;
  showResultCanvas: boolean;
  resultImage?: string;
}

const { windowWidth } = Taro.getSystemInfoSync()

function rpxToPx(rpx) {
  return rpx * windowWidth / 750
}

export default class Index extends Component {
  state: IndexState = {
    name: Taro.getStorageSync('name') || ' ',
    images: [],
    canvasHeight: 0,
    setting: Taro.getMySetting(),
    showResultCanvas: false,
    resultImage: '',
  }

  componentDidShow() {
    const newSetting = Taro.getMySetting()
    if (JSON.stringify(newSetting) !== JSON.stringify(this.state.setting)) {
      this.setState({
        setting: newSetting,
      }, () => {
        this.tryRenderImages(false)
      })
    }

  }

  onShareAppMessage() {
    return Taro.shareResult
  }

  selectImages = async () => {
    const { tempFilePaths } = await Taro.chooseImage({
      sizeType: ['compressed', 'original'],
      sourceType: ['album'],
    })

    const images: ImageInfo[] = []

    for (const tempFilePath of tempFilePaths) {
      const imageInfo = await Taro.getImageInfo({ src: tempFilePath })
      images.push(imageInfo)
    }

    this.setState({
      images,
    }, () => this.tryRenderImages(true))
  }

  tryRenderImages = (enableAutoSave) => {
    console.log('tryRenderImages')
    this.setState({ showResultCanvas: true }, () => {
      Taro.nextTick(() => {
        const ctx = Taro.createCanvasContext('resultCanvas')
        if (this.state.images.length === 0) {
          ctx.setFillStyle('#ffffff')
          ctx.rect(0, 0, windowWidth, windowWidth)
          ctx.fill()
          ctx.draw(false)
          return
        }

        const { setting } = this.state
        const heights = this.state.images.reduce((result: number[], item, index, images) => {
          if (index % 2 === 0) {
            const maxheight = Math.max(item.height * rpxToPx(375) / item.width, images[index + 1] ? (images[index + 1].height * rpxToPx(375) / images[index + 1].width) : 0)
            result.push(maxheight)
          }
          return result
        }, [])
        const nameHeight = setting.watermarkName ? 0 : 40
        const canvasHeight = heights.reduce((result: number, item: number) => {
          return result + item;
        }, nameHeight);
        this.setState({ canvasHeight }, () => {
          ctx.setFillStyle('#ffffff')
          ctx.rect(0, 0, windowWidth, canvasHeight)
          ctx.fill()
          let offsetY = nameHeight;
          (this.state.images || []).forEach((image, index) => {
            if (index > 1 && index % 2 === 0) {
              offsetY += heights[index / 2 - 1]
            }
            ctx.drawImage(image.path, index % 2 * rpxToPx(375), offsetY, rpxToPx(375), image.height * rpxToPx(375) / image.width)
          })
          if (setting.watermarkName) {
            ctx.save()
            ctx.translate(windowWidth / 4, 0)
            for (let h = 0; h < canvasHeight; h += 200) {
              ctx.translate(0, 200);
              
              ctx.setFillStyle('#ff0000')
              ctx.setFontSize(32)
              ctx.setGlobalAlpha(0.4)
              ctx.setTextAlign('center')
              ctx.setTextBaseline('middle')
              
              ctx.rotate(-20 * Math.PI / 180)
              ctx.fillText(this.state.name, 0, 0)
              ctx.rotate(20 * Math.PI / 180)

              ctx.translate(windowWidth / 2, 0)
              ctx.rotate(-20 * Math.PI / 180)
              ctx.fillText(this.state.name, 0, 0)
              ctx.rotate(20 * Math.PI / 180)
              ctx.translate(-windowWidth / 2, 0)

            }
            ctx.restore()
          } else {
            ctx.save()
            ctx.setFillStyle('#000000')
            ctx.setFontSize(18)
            ctx.fillText(this.state.name, 10, 28)
            ctx.restore()
          }
          ctx.draw(false, () => {
            // 为了防止转图片失败，多试几次
            let times = 0
            const resultToImage = () => {
              console.log('resultToImage', times)
              Taro.canvasToTempFilePath({
                x: 0,
                y: 0,
                width: windowWidth,
                height: this.state.canvasHeight,
                destWidth: 1080,
                destHeight: this.state.canvasHeight * 1080 / windowWidth,
                canvasId: 'resultCanvas',
                fileType: 'jpg',
                success: (res) => {
                  this.setState({
                    resultImage: res.tempFilePath,
                    showResultCanvas: false,
                  }, () => {
                    if (enableAutoSave && this.state.name.trim() && this.state.setting.autoSave) {
                      this.saveImage()
                    }
                  })
                },
                fail: () => {
                  if (times < 5) {
                    times++
                    setTimeout(resultToImage, 100)
                  }
                }
              })
            }
            resultToImage()

          })
        })
      })
    })

  }

  timer: undefined | NodeJS.Timeout = undefined

  saveName = (name: string) => {
    if (this.timer) {
      clearTimeout(this.timer)
    }
    this.timer = setTimeout(() => {
      Taro.setStorageSync('name', name);
      this.setState({ name }, async () => {
        this.tryRenderImages(false)
      })
    }, 200)


  }

  saveImage = () => {
    console.log(this.state.resultImage)
    if (this.state.resultImage) {
      Taro.saveImageToPhotosAlbum({
        filePath: this.state.resultImage,
        success: ({ errMsg }) => {
          if (errMsg === "saveImageToPhotosAlbum:ok") {
            Taro.showToast({
              title: '已经保存到相册',
              icon: 'success',
              duration: 2000
            })

          } else {
            Taro.showToast({
              title: '保存失败',
              duration: 2000
            })
          }
        },
        fail: () => {
          Taro.showToast({
            title: '保存失败',
            duration: 2000
          })
        }
      })
    }
  }

  render() {
    console.log()
    return (
      <View className='IndexPage'>

        <View className='form'>
          <Input className='input' placeholder='输入姓名' value={this.state.name.trim()} onInput={(e) => this.saveName(e.detail.value)} />
          <Button className='btn primary' onClick={this.selectImages}>选择图片</Button>
          <Button className='btn' onClick={this.saveImage} disabled={!this.state.name.trim() || this.state.images.length === 0}>保存合图</Button>
        </View>
        <View className='render'>
          {this.state.showResultCanvas ? (
            <Canvas
              canvasId='resultCanvas'
              className='resultCanvas'
              style={{ width: rpxToPx(750), height: `${this.state.canvasHeight}px` }}
            />
          ) : (
            this.state.resultImage ? (
              <Image style={{ width: rpxToPx(750), height: `${this.state.canvasHeight}px` }} src={this.state.resultImage} />
            ) : null
          )}
        </View>
      </View>
    )
  }
}
